home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr47 / sb16snd.zip / SBPLAY.PAS < prev    next >
Pascal/Delphi Source File  |  1995-02-18  |  4KB  |  179 lines

  1. {           Copyright 1995 by Ethan Brodsky.  All rights reserved.           }
  2. program SBPlay; {$X+}
  3.   uses
  4.     CRT,
  5.     DOS,
  6.     SBIO,
  7.     XMS;
  8.   const
  9.     BaseIO = $220;
  10.     IRQ    = 5;
  11.     DMA16  = 5;
  12.     LoadChunkSize = 8192;
  13.     BlockLength   = 256;
  14.   type
  15.     PBuffer = ^TBuffer;
  16.     TBuffer = array[1..2] of array[1..BlockLength] of integer;
  17.   var
  18.     Rate: word;
  19.     FileName: string;
  20.  
  21.     NumSamples: LongInt;
  22.     Buffer: PBuffer;
  23.  
  24.     Handle: word;
  25.     CurSample: LongInt;
  26.     MoveParams: TMoveParams;
  27.  
  28.   function GetParameters(var Rate: word; var FName: string): boolean;
  29.     var
  30.       Code: integer;
  31.       i: byte;
  32.     begin
  33.       GetParameters := false;
  34.       if ParamCount <> 2
  35.         then
  36.           Exit
  37.         else
  38.           begin
  39.             Val(ParamStr(1), Rate, Code);
  40.             if Code <> 0 then Exit;
  41.  
  42.             FName := ParamStr(2);
  43.             for i := 1 to Length(FName) do FName[i] := UpCase(FName[i]);
  44.             GetParameters := true;
  45.           end;
  46.     end;
  47.  
  48.   procedure CopyBlock(Offset: LongInt; Block: byte);
  49.     begin
  50.       with MoveParams do
  51.         begin
  52.           if (CurSample + BlockLength) <= NumSamples
  53.             then Length := BlockLength*2
  54.             else
  55.               begin
  56.                 Length := (NumSamples-CurSample) * 2;
  57.                 FillChar(Buffer^[Block][BlockLength - (Length div 2) + 1], (BlockLength-(Length div 2))*2, $00);
  58.               end;
  59.           SourceHandle  := Handle;
  60.           SourceOffset  := Offset;
  61.           DestHandle    := 0;
  62.           DestOffset    := LongInt(@(Buffer^[Block]));
  63.         end;
  64.       XMSMove(@MoveParams);
  65.     end;
  66.  
  67.   procedure PlayHandler; far;
  68.     var
  69.       Result: word;
  70.       i: word;
  71.     begin
  72.       if CurSample < NumSamples
  73.         then
  74.           begin
  75.             CopyBlock(CurSample*2, CurBlock);
  76.             Inc(CurSample, BlockLength);
  77.           end
  78.         else
  79.           begin
  80.             FillChar(Buffer^[CurBlock], BlockLength*2, $00);
  81.           end;
  82.  
  83.     end;
  84.  
  85.   procedure LoadData;
  86.     var
  87.       f: file;
  88.       Chunk: array[1..LoadChunkSize] of byte;
  89.       Size: LongInt;
  90.       Result, i: word;
  91.     begin
  92.       Assign(f, FileName);  Reset(f, 1);
  93.       Size := FileSize(f); NumSamples := Size div 2;
  94.  
  95.       XMSInit;
  96.       if not(XMSAllocate(Handle, (NumSamples*2 div 1024)+1))
  97.         then
  98.           begin
  99.             writeln('ERROR:  Not enough free XMS');
  100.             writeln('        Bytes required:  ', 2 * NumSamples);
  101.             writeln('        Bytes free:      ', XMSGetFreeMem * 1024);
  102.             Halt(2);
  103.           end;
  104.  
  105.       with MoveParams do
  106.         begin
  107.           SourceHandle := 0;
  108.           SourceOffset := LongInt(@Chunk);
  109.           DestHandle   := Handle;
  110.           DestOffset   := 0;
  111.         end;
  112.       repeat
  113.         if Size > LoadChunkSize
  114.           then MoveParams.Length := LoadChunkSize
  115.           else MoveParams.Length := Size;
  116.           BlockRead(f, Chunk, MoveParams.Length, Result);
  117.           if Result < LoadChunkSize
  118.             then for i := Result+1 to LoadChunkSize do Chunk[i] := 0;
  119.           XMSMove(@MoveParams);
  120.           Inc(MoveParams.DestOffset, MoveParams.Length);
  121.           Dec(Size, MoveParams.Length);
  122.       until Size <= 0;
  123.  
  124.       Close(f)
  125.     end;
  126.  
  127.   procedure Init;
  128.     begin
  129.       LoadData;
  130.       GetBuffer(pointer(Buffer), BlockLength);
  131.       CopyBlock(0, 1);
  132.       CopyBlock(BlockLength, 2);
  133.       CurSample := BlockLength*2;
  134.  
  135.       SetHandler(@PlayHandler);
  136.       SBIO.Init(BaseIO, IRQ, DMA16, Output, Rate);
  137.       StartIO(NumSamples);
  138.     end;
  139.  
  140.   procedure Shutdown;
  141.     begin
  142.       SBIO.Shutdown;
  143.       SetHandler(nil);
  144.  
  145.       XMSFree(Handle);
  146.  
  147.       FreeBuffer(pointer(Buffer));
  148.     end;
  149.  
  150.   begin
  151.     writeln('SBPLAY - Copyright 1995 by Ethan Brodsky.  All rights reserved.');
  152.     if GetParameters(Rate, FileName)
  153.       then
  154.         writeln('Playing ', FileName, ' at ', Rate, ' HZ')
  155.       else
  156.         begin
  157.           writeln('Syntax:  sbrecord <rate> <filename>');
  158.           writeln('Example: sbrecord 22050 data.raw');
  159.           Halt(1);
  160.         end;
  161.  
  162.     Init;
  163.  
  164.     repeat
  165. {      writeln(DMACount:5);}
  166.     until Done or KeyPressed;
  167.  
  168.     if KeyPressed
  169.       then
  170.         begin
  171.           writeln('Output terminated by key press');
  172.           ReadKey;
  173.         end;
  174.  
  175.     Shutdown;
  176.  
  177.     writeln;
  178.   end.
  179.